<?php
namespace app\common\model;
use think\Db;
class TaskDevice extends Base{
	/**
	 * 结束一个设备任务队列
	 * @param  integer|array $id     任务ID（task_device表）||数据(task_device表的一行数据)
	 * @return true|string
	 */
    function finish($id){
    	$task=[];
    	if(is_array($id)){
    		$task=$id;
    	}else{
    		$task=$this->read(['id'=>$id]);
    	}
    	if(empty($task)){
    		return error('数据为空');
    	}
    	$hasDev=model('device')->read(['id'=>$task['device_id']],'id,member_id,is_busy');
    	if($task['state']<1){
    		if(!empty($hasDev)&&$hasDev['is_busy']>0){
    			// 设置设备为悠闲状态
    			$save=model('device')->edit(['id'=>$hasDev['id'],'is_busy'=>0]);
    			if(!$save){
    				return $this->finish($task);
    			}
                // 通知后台设备空闲状态
                model('device')->isBusyNotice($hasDev['member_id'],$hasDev['id'],0);
    		}
    		return success();
    	}
    	Db::startTrans();
    	try{
			$remove=$this->del(['id'=>$task['id']]);
			if(!$remove){
				exception('删除失败',1);
			}		
			$nums=$this->where(['task_id'=>$task['task_id']])->count();
			if(!$nums){ //最后一个任务
				$tasking=model('tasking')->read(['id'=>$task['task_id']]);
				if(!empty($tasking)&&$tasking['type']<=0){
					// 存贮日志
                    $tasking['e_time']=time();      
					model('tasked')->add($tasking->toArray());
				}
				// 所有设备均完成该任务则删除
				if(isset($tasking['id'])){
                    if($tasking['loop']){ //循环任务
                        model('tasking')->edit(['id'=>$tasking['id'],'status'=>0]);
                    }else{
    					$del=model('tasking')->del(['id'=>$tasking['id']]);
    					if(!$del){
    						exception('删除失败',1);
    					}
                    }
				}
			}

			// 设置设备为悠闲状态
			if(!empty($hasDev)&&$hasDev['is_busy']>0){
				$save=model('device')->edit(['id'=>$hasDev['id'],'is_busy'=>0]);
				if(!$save){
					exception('系统繁忙',1);
				}
                
			}
			Db::commit();
    	}catch (\Exception $e) {
    		Db::rollback();
    		return error($e->getMessage(),$e->getCode());
    	}
        // 通知后台设备空闲状态
        model('device')->isBusyNotice($hasDev['member_id'],$hasDev['id'],0);
    	return success();
    }
    /**
     * 通过任务列表移除 任务管理器任务
     * @param  integer $task_id 任务ID
     * @param  integer $state   状态 0:候选 || 1：运行中 || null：所有
     * @return boolean
     */
    function removeAll($task_id=0,$state=0){
    	$where=[
    		'task_id'=>$task_id,
    		'state'=>$state
    	];
    	if(!is_null($state)){
    		$where['state']=$state;
    	}
    	$rs=$this->del($where);
    	if($rs){
    		return true;
    	}
    	return false;
    }

    /**
     * 完成当前的任务并且执行下一个任务
     * @param  integer $member_id 用户ID
     * @param  integer $device_id 设备ID
     * @param  boolean $finish 是否完成当前任务
     * @param  boolean $isStop 是否停止前端继续执行
     * @return true||string            
     */
    function nextTask($member_id,$device_id,$finish=true,$isStop=false){
        $cWhere=[
            'member_id'=>$member_id,
            'device_id'=>$device_id,
        ];
        if($finish){
            $cWhere['state']=1;
            $current=$this->read($cWhere);
            if(!empty($current)){ //此处进行旧任务的删除(结束任务处理)
                $finish=$this->finish($current->toArray());
                if(!$finish['success']){
                    return $finish;
                }
            }
            unset($cWhere['state']);
            // 通知后台(任务管理器)更新列表
            $this->updateDev($member_id,[],$device_id);
            if($isStop){
                $this->stopTask($member_id,[],$device_id);
            }
        }
        
        
        // 查找下一个任务
        $options=[
            'order'=>'state desc,sort',
        ];
        $next=$this->read($cWhere,'id,task_id',$options);
        if(empty($next)){ 
            //是否创建微信消息采集任务
            model('device')->isCreateWxMsgTask($member_id,$device_id);
        }else{
            //执行任务
            $rs=$this->executeTask($next['task_id'],$member_id,$device_id);
            if($rs['success']){
                $this->edit(['id'=>$next['id'],'state'=>1]);
            }
            return $rs;

        }
        return success();
    }
    /**
     * 执行任务(发布一个新的任务到客户端)
     * @param  integer  $task_id   任务ID
     * @param  integer  $member_id 用户ID
     * @param  integer  $device_id 设备ID 针对单设备
     * @return array
     */
    function executeTask($task_id,$member_id,$device_id){
        $task=model('tasking')->getTask(['id'=>$task_id],0,['toArray'=>true]);
        if(!empty($task)&&isset($task[0])){
            if(is_integer(key($task))){
                $task=$task[0];
            }
            $rs=\socket\Socket::client($task,$member_id,$device_id);
            if($rs['success']){
                // 发送消息队列则进行消息状态通知
                $this->sendWxMessage($member_id,$device_id,$task);
                // 设置设备为忙碌状态
                $edit=model('device')->edit(['id'=>$device_id,'is_busy'=>1]);
                if($edit){
                    // 通知后台设备空闲状态
                    model('device')->isBusyNotice($member_id,$device_id,1);
                }
            }
            return $rs;
        }else{ // 该任务已经被删除(移除任务管理器任务)
            $this->removeAll($task_id);
            return error('该任务已经被删除');
        }
    }
    /**
     * 通知后台任务管理器更新任务队列
     * @param  integer $member_id [description]
     * @param  array  $data      [description]
     * @param  integer $device_id [description]
     * @return [type]            [description]
     */
    function updateDev($member_id,$data=[],$device_id=null){
        $data['event']='updateDev';
        if(!is_null($device_id)){
            $data['data']=[$device_id];
        }else if(isset($data['device'])){
            $device_id=$data['device'];
            if(is_string($device_id)){
                $device_id=json_decode($device_id,true);
            }
            $data['data']=$device_id;
        }
        \socket\Socket::admin($data,$member_id,$device_id);
    }
    /**
     * 通知移动端停止执行当前任务（主要用于删除了正在执行的任务时的操作通知）
     * @param  integer $member_id [description]
     * @param  array  $data      [description]
     * @param  integer $device_id [description]
     * @return [type]            [description]
     */
    function stopTask($member_id,$data=[],$device_id=null){
        $data['event']='stopTask';
        \socket\Socket::client($data,$member_id,$device_id);
    }

    private function sendWxMessage($member_id,$device_id,$task){
        if($task['event']=='extraTask'&&$task['action']==2){
            $options=json_decode($task['options'],true);
            if(isset($options['log_id'])){
                $map=[
                    'member_id'=>$member_id,
                    'dev_id'=>$device_id,
                    'send_status'=>0,
                    'id'=>$options['log_id'],
                ];
                $wsMsg=model('weixinlogs')->read($map,'id,soft_id,social_id,send_status');
                if(!empty($wsMsg)){
                    $edit=model('weixinlogs')->edit(['id'=>$wsMsg['id'],'send_status'=>1]);
                    if($edit){
                        $wsMsg['send_status']=1;
                        // 这里可通知前台发送状态
                        model('weixinlogs')->wsMsgSendStatus($member_id,$device_id,$wsMsg);
                    }

                }
            }
        }
    }
    
}
